package com.magicalcoder.youyamvc.core.service;

import com.magicalcoder.youyamvc.core.common.utils.MapUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class CommonServiceImpl<T> {
    private static final String ignoreSuffix = "Ignore_";
    private static final String notIgnoreSuffix = "NotIgnore_";

    public ICommonMapper<T> commonMapper;

    public T getModel(Long id) {
        Map<String,Object> query = new HashMap<String,Object>();
        query.put("id", id);
        return commonMapper.getModel(query);
    }
    public T getModelIgnore(Long id,String ... ignoreFields) {
        Map<String,Object> query = new HashMap<String,Object>();
        query.put("id", id);
        addIgnoreFields(query, ignoreFields);
        return commonMapper.getModel(query);
    }



    public T getModelNotIgnore(Long id,String ... notIgnoreFields) {
        Map<String,Object> query = new HashMap<String,Object>();
        query.put("id", id);
        addNotIgnoreFields(query, notIgnoreFields);
        return commonMapper.getModel(query);
    }



    public T selectOneModelWillThrowException(Map<String, Object> query){
        return commonMapper.getModel(query);
    }
    public T selectOneModelWillThrowExceptionIgnore(Map<String, Object> query,String ... ignoreFields){
        if(query == null){query = new HashMap<>();}
        addIgnoreFields(query,ignoreFields);
        return commonMapper.getModel(query);
    }
    public T selectOneModelWillThrowExceptionNotIgnore(Map<String, Object> query,String ... notIgnoreFields){
        if(query == null){query = new HashMap<>();}
        addNotIgnoreFields(query,notIgnoreFields);
        return commonMapper.getModel(query);
    }

    public T selectFirstModel(Map<String, Object> query){
        if(query == null){query = new HashMap<>();}
        query.put("limit",1);
        List<T> list = commonMapper.getModelList(query);
        if(list!=null && list.size()>0){
            return list.get(0);
        }
        return null;
    }

    public T selectFirstModelIgnore(Map<String, Object> query,String ... ignoreFields){
        if(query == null){query = new HashMap<>();}
        query.put("limit",1);
        addIgnoreFields(query,ignoreFields);
        List<T> list = commonMapper.getModelList(query);
        if(list!=null && list.size()>0){
            return list.get(0);
        }
        return null;
    }
    public T selectFirstModelNotIgnore(Map<String, Object> query,String ... notIgnoreFields){
        if(query == null){query = new HashMap<>();}
        query.put("limit",1);
        addNotIgnoreFields(query,notIgnoreFields);
        List<T> list = commonMapper.getModelList(query);
        if(list!=null && list.size()>0){
            return list.get(0);
        }
        return null;
    }
    public List<T> getModelList(Map<String, Object> query) {
        return commonMapper.getModelList(query);
    }

    public List<T> getModelListIgnore(Map<String, Object> query,String ... ignoreFields) {
        if(query == null){query = new HashMap<>();}
        addIgnoreFields(query,ignoreFields);
        return commonMapper.getModelList(query);
    }
    public List<T> getModelListNotIgnore(Map<String, Object> query,String ... notIgnoreFields) {
        if(query == null){query = new HashMap<>();}
        addNotIgnoreFields(query,notIgnoreFields);
        return commonMapper.getModelList(query);
    }
    public List<T> getModelInList(Set<Long> idList) {
        if(idList==null || idList.isEmpty()){
            return null;
        }
        return commonMapper.getModelInList(MapUtil.buildMap("idList",idList));
    }
    public List<T> getModelInListIgnore(Set<Long> idList,String ... ignoreFields) {
        if(idList==null || idList.isEmpty()){
            return null;
        }
        Map<String,Object> query = new HashMap<>();
        addIgnoreFields(query,ignoreFields);
        query.put("idList",idList);
        return commonMapper.getModelList(query);
    }
    public List<T> getModelInListNotIgnore(Set<Long> idList,String ... notIgnoreFields) {
        if(idList==null || idList.isEmpty()){
            return null;
        }
        Map<String,Object> query = new HashMap<>();
        addNotIgnoreFields(query,notIgnoreFields);
        query.put("idList",idList);
        return commonMapper.getModelInList(query);
    }

    public Integer getModelListCount(Map<String, Object> query) {
        return commonMapper.getModelListCount(query);
    }

    public int insertModel(T model) {
        return commonMapper.insertModel(model);
    }

    public int replaceModel(T model) {
        return commonMapper.replaceModel(model);
    }
    public int updateModel(T model) {
        return commonMapper.updateModel(model);
    }

    public int updateModelWithoutNull(T model) {
        return commonMapper.updateModelWithoutNull(model);
    }
    public int deleteModel(Long id) {
        Map<String,Object> query = new HashMap<String,Object>();
        query.put("id", id);
       return commonMapper.deleteModel(query);
    }
    public int deleteModelList(Map<String,Object> model){
        return commonMapper.deleteModelList(model);
    }

    public void truncateModel() {
        commonMapper.truncateModel();
    }

    public int batchInsertModel(List<T> list) {
        return commonMapper.batchInsertModel(list);
    }

    public int batchReplaceModel(List<T> list) {
        return commonMapper.batchReplaceModel(list);
    }

    public int batchUpdateModel(List<T> list) {
        return commonMapper.batchUpdateModel(list);
    }

    public int batchDeleteModel(List<Long> idList) {
        return commonMapper.batchDeleteModel(idList);
    }

    public int batchDeleteModelList(List<T> modelList){
        return commonMapper.batchDeleteModelList(modelList);
    }

//    @Transactional
    public void transactionImportJsonList(List<T> list){
        /*if(list!=null && list.size()>0){
            for(Goods goods : list){
                if (goods.getId() == null) {
                    insertModel(goods);
                } else {
                    Goods model = getModel(goods.getId());
                    if(model==null){
                        insertModel(goods);
                    }else {
                        CopyUtil.copy(goods, model);
                        updateModel(model);
                    }
                }
            }
        }*/
    }

    private void addIgnoreFields(Map<String, Object> query, String[] ignoreFields) {
        if(ignoreFields!=null && ignoreFields.length>0){
            query.put(ignoreSuffix,true);
            for(String field:ignoreFields){
                query.put(new StringBuilder(field).append(ignoreSuffix).toString(),true);
            }
        }
    }
    private void addNotIgnoreFields(Map<String, Object> query, String[] notIgnoreFields) {
        if(notIgnoreFields!=null && notIgnoreFields.length>0){
            query.put(notIgnoreSuffix,true);
            for(String field:notIgnoreFields){
                query.put(new StringBuilder(field).append(notIgnoreSuffix).toString(),true);
            }
        }
    }

}
